home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / Libraries / CW GUSI 1.6.4 / src / GUSIMPWFile.cp < prev    next >
Text File  |  1995-06-21  |  8KB  |  346 lines

  1. /*********************************************************************
  2. Project    :    GUSI                -    Grand Unified Socket Interface
  3. File        :    GUSIMPWFile.cp    -    MPW compatible file sockets
  4. Author    :    Matthias Neeracher <neeri@iis.ee.ethz.ch>
  5. Language    :    MPW C
  6.  
  7. $Log: GUSIMPWFile.cp,v $
  8. Revision 1.2  1994/12/30  20:10:03  neeri
  9. fRefNum is obtained lazily.
  10. Add specialized fstat() member.
  11.  
  12. Revision 1.1  1994/08/10  00:23:40  neeri
  13. Initial revision
  14.  
  15. *********************************************************************/
  16.  
  17. #include "GUSIFile_P.h"
  18.  
  19. #include <IOCtl.h>
  20. #include <StdIO.h>
  21. #include <StdLib.h>
  22. #include <SetJmp.h>
  23.  
  24. #if defined(powerc) || defined(__powerc)
  25. #include <FragLoad.h>
  26. #endif
  27.  
  28. MPWDomain MPWSockets;
  29.  
  30. /*********************** Prototypes for MPW routines ***********************/
  31.  
  32. #if !defined(powerc) && !defined(__powerc)
  33. extern "C" {
  34. #pragma pointers_in_D0
  35. int MPW_open(const char * name, int flags);
  36. int MPW_close(int s);
  37. int MPW_read(int s, char *buffer, unsigned buflen);
  38. int MPW_write(int s, char *buffer, unsigned buflen);
  39. int MPW_fcntl(int s, unsigned int cmd, int arg);
  40. int MPW_ioctl(int d, unsigned int request, long *argp);  /* argp is really a caddr_t */
  41. long MPW_lseek(int fd, long offset, int whence);
  42. int MPW_faccess(char *fileName, unsigned int cmd, long * arg);
  43. char * MPW_getenv(const char *env);
  44. #pragma pointers_in_A0
  45. }
  46. #else
  47. static int (*MPW_open)(const char * name, int flags);
  48. static int (*MPW_close)(int s);
  49. static int (*MPW_read)(int s, char *buffer, unsigned buflen);
  50. static int (*MPW_write)(int s, char *buffer, unsigned buflen);
  51. static int (*MPW_fcntl)(int s, unsigned int cmd, int arg);
  52. static int (*MPW_ioctl)(int d, unsigned int request, long *argp);  /* argp is really a caddr_t */
  53. static long (*MPW_lseek)(int fd, long offset, int whence);
  54. static int (*MPW_faccess)(char *fileName, unsigned int cmd, long * arg);
  55. static char * (*MPW_getenv)(const char *env);
  56.  
  57. static Boolean DidInitStandardLib = false;
  58.  
  59. static void InitStandardLib()
  60. {
  61.     ConnectionID     StdCLib;
  62.     SymClass            symClass;
  63.     Ptr                 whoCares;
  64.     Str255            error;
  65.         
  66.     DidInitStandardLib = true;
  67.     
  68.     if (GetSharedLibrary(
  69.             StringPtr("\pStdCLib"), kPowerPCArch, kLoadLib, &StdCLib, &whoCares, error)
  70.     )
  71.         return;
  72.     
  73.     if (FindSymbol(StdCLib, StringPtr("\popen"), (Ptr *) &MPW_open, &symClass))
  74.         goto failed_on_open;
  75.     if (FindSymbol(StdCLib, StringPtr("\pclose"), (Ptr *) &MPW_close, &symClass))
  76.         goto failed_on_close;
  77.     if (FindSymbol(StdCLib, StringPtr("\pread"), (Ptr *) &MPW_read, &symClass))
  78.         goto failed_on_read;
  79.     if (FindSymbol(StdCLib, StringPtr("\pwrite"), (Ptr *) &MPW_write, &symClass))
  80.         goto failed_on_write;
  81.     if (FindSymbol(StdCLib, StringPtr("\pfcntl"), (Ptr *) &MPW_fcntl, &symClass))
  82.         goto failed_on_fcntl;
  83.     if (FindSymbol(StdCLib, StringPtr("\pioctl"), (Ptr *) &MPW_ioctl, &symClass))
  84.         goto failed_on_ioctl;
  85.     if (FindSymbol(StdCLib, StringPtr("\plseek"), (Ptr *) &MPW_lseek, &symClass))
  86.         goto failed_on_lseek;
  87.     if (FindSymbol(StdCLib, StringPtr("\pfaccess"), (Ptr *) &MPW_faccess, &symClass))
  88.         goto failed_on_faccess;
  89.     if (FindSymbol(StdCLib, StringPtr("\pgetenv"), (Ptr *) &MPW_getenv, &symClass))
  90.         goto failed_on_getenv;
  91.  
  92.     return;
  93.     
  94. failed_on_getenv:
  95.     MPW_getenv = nil;
  96. failed_on_faccess:
  97.     MPW_faccess = nil;
  98. failed_on_lseek:
  99.     MPW_lseek = nil;
  100. failed_on_ioctl:
  101.     MPW_ioctl = nil;
  102. failed_on_fcntl:
  103.     MPW_fcntl = nil;
  104. failed_on_write:
  105.     MPW_write = nil;
  106. failed_on_read:
  107.     MPW_read = nil;
  108. failed_on_close:
  109.     MPW_close = nil;
  110. failed_on_open:
  111.     MPW_open = nil;
  112. }
  113.  
  114. #endif
  115.  
  116. /************************ MPWFileSocket members ************************/
  117.  
  118. #define MPW_O_RDONLY         0         /* Bits 0 and 1 are used internally */
  119. #define MPW_O_WRONLY         1         /* Values 0..2 are historical */
  120. #define MPW_O_RDWR          2        /* NOTE: it goes 0, 1, 2, *!* 8, 16, 32, ... */
  121. #define MPW_O_APPEND        (1<< 3)        /* append (writes guaranteed at the end) */
  122. #define MPW_O_RSRC         (1<< 4)        /* Open the resource fork */
  123. #define MPW_O_ALIAS        (1<< 5)        /* Open alias file */
  124. #define MPW_O_CREAT        (1<< 8)        /* Open with file create */
  125. #define MPW_O_TRUNC        (1<< 9)        /* Open with truncation */
  126. #define MPW_O_EXCL         (1<<10)     /* w/ O_CREAT:  Exclusive "create-only" */
  127. #define MPW_O_BINARY        (1<<11)     /* Open as a binary stream */
  128. #define MPW_O_NRESOLVE    (1<<14)        /* Don't resolve any aliases */
  129.  
  130. static int TranslateOpenFlags(int mode)
  131. {
  132.     int mpwMode;
  133.     
  134.     switch (mode & 3) {
  135.     case O_RDWR:
  136.         mpwMode = MPW_O_RDWR;
  137.         break;
  138.     case O_RDONLY:
  139.         mpwMode = MPW_O_RDONLY;
  140.         break;
  141.     case O_WRONLY:
  142.         mpwMode = MPW_O_WRONLY;
  143.         break;
  144.     }
  145.     if (mode & O_APPEND)
  146.         mpwMode |= MPW_O_APPEND;
  147.     if (mode & O_CREAT)
  148.         mpwMode |= MPW_O_CREAT;
  149.     if (mode & O_EXCL)
  150.         mpwMode |= MPW_O_EXCL;
  151.     if (mode & O_TRUNC)
  152.         mpwMode |= MPW_O_TRUNC;
  153.     if (mode & O_BINARY)
  154.         mpwMode |= MPW_O_BINARY;
  155.     
  156.     return mpwMode;
  157. }
  158.  
  159. MPWFileSocket * MPWFileSocket::open(const char * name, int flags)
  160. {
  161. #if defined(powerc) || defined(__powerc)
  162.     if (!DidInitStandardLib)
  163.         InitStandardLib();
  164.     if (!MPW_open)
  165.         return (MPWFileSocket *) GUSI_error_nil(ENOEXEC);
  166. #endif
  167.  
  168.     int                    fd        =    MPW_open(name, TranslateOpenFlags(flags));
  169.     MPWFileSocket *    sock;
  170.     
  171.     if (fd == -1)
  172.         return (MPWFileSocket *) nil;
  173.     else if (sock = new MPWFileSocket(fd))
  174.         return sock;
  175.     else
  176.         return (MPWFileSocket *)GUSI_error_nil(ENOMEM);
  177. }
  178.  
  179. MPWFileSocket * MPWFileSocket::stdopen(int fd)
  180. {
  181. #if defined(powerc) || defined(__powerc)
  182.     if (!DidInitStandardLib)
  183.         InitStandardLib();
  184.     if (!MPW_open)
  185.         return (MPWFileSocket *) GUSI_error_nil(ENOEXEC);
  186. #endif
  187.  
  188.     MPWFileSocket *    sock;
  189.     
  190.     if (sock = new MPWFileSocket(fd))
  191.         return sock;
  192.     else
  193.         return (MPWFileSocket *)GUSI_error_nil(ENOMEM);
  194. }
  195.  
  196. MPWFileSocket::MPWFileSocket(int fd)
  197.     : FileSocket(0), fd(fd)
  198. {
  199.     if (!MPW_open)
  200.         GUSI_error(ENOEXEC);    
  201. }
  202.  
  203. int MPWFileSocket::read(void * buffer, int buflen)
  204. {
  205.     return MPW_read(fd, (char *) buffer, buflen);
  206. }
  207.  
  208. int MPWFileSocket::write(void * buffer, int buflen)
  209. {
  210.     return MPW_write(fd, (char *) buffer, buflen);
  211. }
  212.  
  213. int MPWFileSocket::fcntl(unsigned int cmd, int arg)
  214. {
  215.     return MPW_fcntl(fd, cmd, arg);
  216. }
  217.  
  218. int MPWFileSocket::ioctl(unsigned int request, void *argp)
  219. {
  220.     return MPW_ioctl(fd, request, (long *) argp);
  221. }
  222.  
  223. long MPWFileSocket::lseek(long offset, int whence)
  224. {
  225.     long    res;
  226.     Ptr    buf;
  227.  
  228.     res = MPW_lseek(fd, offset, whence);
  229.     
  230.     if (res != -1)
  231.         return res;
  232.         
  233.     if (whence != SEEK_SET) {
  234.         res = MPW_lseek(fd, 0, whence);
  235.         
  236.         if (res == -1)
  237.             return res;
  238.             
  239.         offset += res;
  240.     }
  241.     
  242.     res = MPW_lseek(fd, 0, SEEK_END);
  243.     
  244.     buf = NewPtrClear(1024);
  245.     
  246.     while (offset >= res + 1024)
  247.         if (MPW_write(fd, buf, 1024) == -1)
  248.             return -1;
  249.         else
  250.             res += 1024;
  251.  
  252.     if (offset > res && MPW_write(fd, buf, unsigned(offset-res)) == -1)
  253.         return -1;
  254.  
  255.     return offset;
  256. }
  257.  
  258. int MPWFileSocket::ftruncate(long offset)
  259. {
  260.     if (lseek(offset, SEEK_SET) == -1)
  261.         return -1;
  262.     
  263.     if (MPW_ioctl(fd, FIOSETEOF, (long *) offset) == -1)
  264.         return -1;
  265.     
  266.     return 0;
  267. }
  268.  
  269. int MPWFileSocket::fstat(struct stat * buf)
  270. {
  271.     short    fRef;
  272.     
  273.     if (fRefNum || MPW_ioctl(fd, FIOREFNUM, (long *) &fRef) != -1) {
  274.         if (!fRefNum)
  275.             SetFRefNum(fRef);
  276.  
  277.         return FileSocket::fstat(buf);
  278.     } else {
  279.         // Pseudofile
  280.         
  281.         buf->st_dev            =    0;
  282.         buf->st_ino            =    0;
  283.         buf->st_mode        =    S_IFCHR | 0666;
  284.         buf->st_nlink        =    1;
  285.         buf->st_uid            =    0;
  286.         buf->st_gid            =    0;
  287.         buf->st_rdev        =    0;
  288.         buf->st_size        =    1;
  289.         buf->st_atime        =    time(NULL);
  290.         buf->st_mtime        =    time(NULL);
  291.         buf->st_ctime        =    time(NULL);
  292.         buf->st_blksize    =    1;
  293.         buf->st_blocks        =    1;
  294.  
  295.         return 0;
  296.     }
  297. }
  298.  
  299. int MPWFileSocket::isatty()
  300. {
  301.     short    fRef;
  302.     
  303.     return MPW_ioctl(fd, FIOREFNUM, (long *) &fRef) == -1;
  304. }
  305.  
  306. MPWFileSocket::~MPWFileSocket()
  307. {
  308.     MPW_close(fd);
  309. }
  310.  
  311. char *getenv(const char * name)
  312. {
  313. #ifdef powerc
  314.     if (!DidInitStandardLib)
  315.         InitStandardLib();
  316.     if (!MPW_getenv)
  317.         return NULL;
  318. #endif
  319.     return MPW_getenv(name);
  320. }
  321.  
  322. /********************* PPCSocketDomain member **********************/
  323.  
  324. MPWFileSocket * (*MPWDomain::open)(const char * name, int flags) = nil;
  325. MPWFileSocket * (*MPWDomain::stdopen)(int fd)                          = nil;
  326.  
  327. MPWDomain::MPWDomain()
  328.     :    SocketDomain(AF_UNSPEC)    
  329. {
  330. #ifdef powerc
  331.     extern jmp_buf __program_exit, __target_for_exit;
  332.     memcpy(__program_exit, __target_for_exit, 70*sizeof(long *));
  333. #endif
  334.     
  335.     open                 = MPWFileSocket::open;
  336.     stdopen            = MPWFileSocket::stdopen;
  337. }
  338.  
  339. extern "C" void RemoveConsole(void)
  340. {
  341. }
  342.  
  343. extern "C" void _coreIOExit(void)
  344. {
  345. }
  346.